package com.test.modules.sequence.service.impl;

import com.test.modules.sequence.service.BizCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * #
 * # Add some message
 * <p>
 * 2019/3/7
 * #
 *
 * @author qd-hz
 */
@Service
public class RedisBizCodeServiceImpl implements BizCodeService {
    /** 让当key第一次使用时，设置其有效期 */
    private static final String LUA_SCRIPT = "local current = redis.call('incr', KEYS[1]); " +
            "if current == 1 then redis.call('expire', KEYS[1], ARGV[1]) end; " +
            "return current;";

    private static final String KEY_PREFIX_ORDER = "order";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     *
     * @param key 键
     * @param duration 有效期（秒）
     * @return 下一个序列值
     */
    private long nextValue(String key, int duration) {
        RedisScript<Long> script = new DefaultRedisScript<Long>(LUA_SCRIPT, Long.class);
        List<String> list = new ArrayList<String>(1);
        list.add(key);
        Object[] args = new Object[]{String.valueOf(duration)};
         Long sequ = stringRedisTemplate.execute(script, list, args);
        return sequ.longValue();
    }

    public String getOrderNo() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
        String timestamp = sdf.format(new Date());

        long nextValue = nextValue(KEY_PREFIX_ORDER + timestamp, 10);

        String result = timestamp + "-" + nextValue;

        return result;
    }
}
